package main.leetcode.primary.from401to500;

import java.util.LinkedList;
import java.util.List;

/**
 * 442. 数组中重复的数据
 *
 * <p>给定一个整数数组 a，其中1 ≤ a[i] ≤ n （n为数组长度）, 其中有些元素出现两次而其他元素出现一次。
 *
 * <p>找到所有出现两次的元素。
 *
 * <p>你可以不用到任何额外空间并在O(n)时间复杂度内解决这个问题吗？
 *
 * <p>示例：<br>
 * 输入: [4,3,2,7,8,2,3,1] <br>
 * 输出: [2,3]
 */
public class ex442 {
    public List<Integer> findDuplicates(int[] nums) {
        int n = nums.length;

        for (int i = 0; i < n; ++i) {
            while (nums[nums[i] - 1] != nums[i]) {
                exch(nums, i, nums[i] - 1);
            }
        }

        List<Integer> res = new LinkedList<>();
        for (int i = 0; i < n; ++i) {
            if (nums[i] != i + 1) {
                res.add(nums[i]);
            }
        }

        return res;
    }

    private void exch(int[] nums, int i, int j) {
        nums[i] = nums[i] + nums[j] - (nums[j] = nums[i]);
    }
}
